.TH std::atomic_ref::atomic_ref 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::atomic_ref::atomic_ref \- std::atomic_ref::atomic_ref

.SH Synopsis
   explicit atomic_ref( T& obj );                \fB(1)\fP \fI(since C++20)\fP
   atomic_ref( const atomic_ref& ref ) noexcept; \fB(2)\fP \fI(since C++20)\fP

   Constructs a new atomic_ref object.

   1) Constructs an atomic_ref object referencing the object obj. The behavior is
   undefined if obj is not aligned to required_alignment.
   2) Constructs an atomic_ref object referencing the object referenced by ref.

.SH Parameters

   obj - object to reference
   ref - another atomic_ref object to copy from

.SH Example

   The program increments the values in a container using several threads. Then the
   final sum is printed. Non-atomic access may "loss" the results of some operations
   due to data-races.


// Run this code

 #include <atomic>
 #include <iostream>
 #include <numeric>
 #include <thread>
 #include <vector>

 int main()
 {
     using Data = std::vector<char>;

     auto inc_atomically = [](Data& data)
     {
         for (Data::value_type& x : data)
         {
             auto xx = std::atomic_ref<Data::value_type>(x);
             ++xx; // atomic read-modify-write
         }
     };

     auto inc_directly = [](Data& data)
     {
         for (Data::value_type& x : data)
             ++x;
     };

     auto test_run = [](const auto Fun)
     {
         Data data(10'000'000);
         {
             std::jthread j1{Fun, std::ref(data)};
             std::jthread j2{Fun, std::ref(data)};
             std::jthread j3{Fun, std::ref(data)};
             std::jthread j4{Fun, std::ref(data)};
         }
         std::cout << "sum = " << std::accumulate(cbegin(data), cend(data), 0) << '\\n';
     };

     test_run(inc_atomically);
     test_run(inc_directly);
 }

.SH Possible output:

 sum = 40000000
 sum = 39994973
